﻿using Kyoh.Lib.Win32API;
using Kyoh.Lib.Win32API.Shell;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Kyoh.Lib.WinForms
{
    public class ExtractIcons
    {
        #region Get Folder Icons

        public static Icon GetIcon(string strPath, bool selected, ImageList imageList)
        {
            var info = new ShFileInfoW
                {
                    hIcon = IntPtr.Zero,
                    iIcon = 0,
                    dwAttributes = 0,
                    szDisplayName = "",
                    szTypeName = "",
                };
            int cbFileInfo = Marshal.SizeOf(info);
            ShellFileInfoFlags flags;
            if (!selected)
                flags =
                    ShellFileInfoFlags.Icon |
                    ShellFileInfoFlags.SmallIcon |
                    ShellFileInfoFlags.TypeName |
                    ShellFileInfoFlags.DisplayName;
            else
                flags =
                    ShellFileInfoFlags.Icon |
                    ShellFileInfoFlags.SmallIcon |
                    ShellFileInfoFlags.OpenIcon |
                    ShellFileInfoFlags.TypeName |
                    ShellFileInfoFlags.DisplayName;

            NativeMethods.ShGetFileInfo(
                strPath,
                0, 
                ref info,
                (uint) cbFileInfo,
                flags);
            return Icon.FromHandle(info.hIcon);
        }

        #endregion

        #region Get Desktop Icon

        // Retreive the desktop icon from Shell32.dll - it always appears at index 34 in all shell32 versions.
        // This is probably NOT the best way to retreive this icon, but it works - if you have a better way
        // by all means let me know..

        //		[DllImport("Shell32.dll", CharSet=CharSet.Auto)]
        //		public static extern IntPtr ExtractIcon(int hInst, string lpszExeFileName, int nIconIndex);
        //
        //		public static Icon GetDesktopIcon()
        //		{
        //			IntPtr i = ExtractIcon(0, Environment.SystemDirectory + "\\shell32.dll", 34);
        //			return Icon.FromHandle(i);
        //		}

        // Updated this method in v1.11 so that the icon returned is a small icon, not a large icon as
        // returned by the old method above

        [DllImport("Shell32.dll", CharSet = CharSet.Auto)]
        public static extern uint ExtractIconEx(
            string lpszFile, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons);

        public static Icon GetDesktopIcon()
        {
            var handlesIconLarge = new IntPtr[1];
            var handlesIconSmall = new IntPtr[1];
            ExtractIconEx(Environment.SystemDirectory + "\\shell32.dll", 34,
                          handlesIconLarge, handlesIconSmall, 1);

            return Icon.FromHandle(handlesIconSmall[0]);
        }

        #endregion

    }
}
